/*
 * This file is part of LexiToolsMobile
 *  
 * Author: Jerzy Wawro, Jozef Kamycki
 * ver. 1.00
 * Copyright: Tenar (http://www.tenar.pl)
 *
 * Mobile LexiTools is an open source project; you can redistribute it 
 * and/or modify it under the terms of the license as published -  GPL with 
 * the following modification:  fragments of the code may be not copyleft 
 * (hidden), to protect contents of the dicionaries.
 * In this case the author of non-public fragments of the code is obliged 
 * to make available functionally equivalent code for unprotected dictionaries.
 * 
 * Mobile LexiTools is distributed WITHOUT ANY WARRANTY.
 * See the license for more details.
 *  
 * You should have received a copy of the GNU General Public License
 * along with LexiToolsMobile (see: gpl.txt); if not - you can find it 
 * on web page http://www.fsf.org/, or write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */


package lt.main;

import javax.microedition.lcdui.*;

import lt.util.str;
import dict.warp;
import com.Callback;
import com.InternetConnection;
import com.Receiver;


/****************************************** Threads *********************************************************/

class threadDict implements Runnable {
    public static final int STATE_INIT = 0;
    public static final int STATE_WAIT = 1;
    public static final int STATE_FIRST_PREVIEW = 2;
    public static final int STATE_NEXT_PREVIEW = 3;
    public static final int STATE_FIRST_EQ = 4;
    public static final int STATE_NEXT_EQ = 5;
    public static final int STATE_STOP = 9;


    warp dict;
    params par;
    int state;
    int next_state;
    private Object semaphore = new Object();
    String key;
    StringItem[] PList;
    String[] PListS;
    
    boolean buffered = false;
    String[] bufEquiv; 
    int bufEquivCount;
    
    List eqList;
    Image img;
    int ecounter;
    int pcounter;
    boolean bFirstEq = false;
    boolean bOnlyExamples = false;

    public threadDict(warp adict, params apar) {
        dict=adict;
        par=apar;
        state=STATE_INIT;
        next_state=STATE_INIT;
        PListS = new String[par.iPreviewMax];
        if (buffered)  bufEquiv = new String[par.iEquivMax];
    }

    void StartPreview(String sKey, StringItem[] list) {

        synchronized(semaphore) {
            if ( (next_state!=STATE_FIRST_EQ) && (next_state!=STATE_NEXT_EQ) ) {
                key=str.convProgrammersKbd(sKey);
                PList=list;
                next_state=STATE_FIRST_PREVIEW;
            } 
            semaphore.notify();
        }

    }
    
    void StartEquiv(boolean onlyExamples, String sKey, List list, Image aimg) {
        synchronized(semaphore) {
            key=str.convProgrammersKbd(sKey);
            bOnlyExamples=onlyExamples;
            eqList=list;
            img=aimg;
            next_state=STATE_FIRST_EQ;
            semaphore.notify();
        }
    }
    
    void FirstPreview() {
        int i1, i2;
        boolean b;
        char ch;
        String s;
        

        pcounter=0;
//        for (i1=0; i1<PList.length; i1++) PList[i1].setText(par.sBlank);
        for (i1=0;i1<par.iPreviewMax;i1++) PListS[i1]="";
        if (key.length() != 0) {
            try {
                s = dict.FindFirst(par.dictDirection, false, false, key);
            }
            catch(Exception e) {
                e.printStackTrace();
                s = "dict.error";
            }
            i1=s.indexOf(key);
            if (i1<0) return;
            if (i1>0) {
                i2=s.indexOf(" "+key)+1;
                if (i2>0) i1=i2;
            }
            i2=i1; b=true;
            while ((i2<s.length()) && b) {
                        ch=s.charAt(i2);
                        if ((ch==' ') || (ch==',') || (ch==':') || (ch==')') || (ch==']')) b=false;
                        else i2++;
            }
            if (b) {
                s=s.substring(i1,s.length());
            }
            else {
                s=s.substring(i1,i2);
            }
            PListS[0]=s;
            // PList[0].setText(s);
        }
        pcounter=1;
        
    }
            

  
    void NextPreview() {
      int i1, i2;
      boolean b;
      char ch;
      String s;
        

      if (key.length() == 0) {
          pcounter++;
      } else {
          try {
            s = dict.FindNext(par.dictDirection, false);
            i1=s.indexOf(key);
            if (i1<0) {
                pcounter++;
                return;
            }
            if (i1>0) {
                i2=s.indexOf(" "+key)+1;
                if (i2<=0) i2=s.indexOf("-"+key)+1;
                if (i2<=0) i2=s.indexOf("/"+key)+1;
                if (i2<=0) i2=s.indexOf(","+key)+1;
                if (i2<=0) i2=s.indexOf(":"+key)+1;
                if (i2<=0) i2=s.indexOf(";"+key)+1;
                if (i2>0) i1=i2;
            }
            i2=i1; b=true;
            while ((i2<s.length()) && b) {
                        ch=s.charAt(i2);
                        if ((ch=='-') || (ch=='.') || (ch==' ') || (ch==',') || (ch==':') || (ch==')') || (ch==']')) b=false;
                        else i2++;
            }
            if (b) {
                s=s.substring(i1,s.length());
            }
            else {
                s=s.substring(i1,i2);
            }
          }
          catch(Exception e) {
                e.printStackTrace();
                s = "dict.error";
          }
          i1=0;
          while ( (i1<par.iPreviewMax) && 
                  ((PListS[i1]!=null) && (PListS[i1].compareTo("")!=0)) &&
                  (s.compareTo(PListS[i1]) != 0 ) ){
                    i1++;
          }
          if ((i1<par.iPreviewMax) && (PListS[i1]!=null) && (PListS[i1].compareTo("")==0)) {
            PListS[i1]=s;
            pcounter++;
          }
       }
    }
           
    void DisplayPreview() {
      int i;
       
      for (i=0; (i<PList.length); i++) {
          if (i>=pcounter) PList[i].setText(par.sBlank);
          else if ((PListS[i]==null)  || PListS[i].equals("")) PList[i].setText(par.sBlank);
          else PList[i].setText(PListS[i]);
       }
    }
           
    void FirstEquiv() {
        String s;
        int i;

//debug eqList.append("start",null);
        bFirstEq=true;
//#if MIDP=="1.0"
//#         int i;
//#         for (i=eqList.size();i>0;i--) {
//#             eqList.delete(i);
//#         }
//#else                 
        eqList.deleteAll();
//#endif        
        eqList.append(par.sSEARCHING,null);
        if (key.length() != 0) {
            try {
//debug eqList.append("searching+",null);
                s = dict.FindFirst(par.dictDirection, true, true, key);
//debug eqList.append("searching-",null);
//debug eqList.append(s,null);
            }
            catch(Exception e) {
                e.printStackTrace();
                s = "dict.error";
            }
            if (s.length()==0) {
                return;
            }
            if (bOnlyExamples) {
                i=s.indexOf("[");
                if (i<0) return;                
            }
            i = s.indexOf(key+" :");
            if ((i!=0) && buffered) {
                bufEquiv[0]=s;
                bufEquivCount=1;
            }
            else {
              bFirstEq=false;
              if (par.iBROWSER_SEPARATE_LANG==1) { 
                // zmienic wyszukiwanie, zeby tego nie bylo trzeba rozdzielac
                i=s.indexOf(":");
                if (i>0) {
                    eqList.set(0,s.substring(0,i-1),img);
                    eqList.append(s.substring(i+2,s.length()),null);
                } else  eqList.set(0,s,img);
              } else {
                eqList.set(0,s,img);    
              }
            }
        }
//debug eqList.append("OK",null);
    }
            

  
    void NextEquiv() {
        String s;
        int i;

        if (key.length() != 0) {
            try {
                s = dict.FindNext(par.dictDirection, true);
            }
            catch(Exception e) {
                e.printStackTrace();
                s = "?"; //dict.error";
            }
            if (bOnlyExamples) {
                i=s.indexOf("[");
                if (i<0) return;                
            }
            if (s.length()>0) {
                i = s.indexOf(key+" :");
                if ((i!=0) && buffered) {
                    if (bufEquivCount<par.iEquivMax) {
                        bufEquiv[bufEquivCount]=s;
                        bufEquivCount++;
                    }
                }
                else {

                  if (par.iBROWSER_SEPARATE_LANG==1) { 
                   // zmienic wyszukiwanie, zeby tego nie bylo trzeba rozdzielac
                    i=s.indexOf(":");
                    if (i>0) {
                        if (bFirstEq) {
                            eqList.set(0,s.substring(0,i-1),img);
                            bFirstEq=false;
                        }
                        else eqList.append(s.substring(0,i-1),img);
                        eqList.append(s.substring(i+2,s.length()),null);
                    } else  eqList.append(s,img);
                  } else {
                    if (bFirstEq) {
                      eqList.set(0,s,img);
                      bFirstEq=false;
                    } else {
                      eqList.append(s,img);
                    }
                  }
                    
                }
            }
        }
  }

void FlushBufEquiv1(int ic)
{
    String s;
    int i;

      if (par.iBROWSER_SEPARATE_LANG==0) { 
        if (bFirstEq) {
            eqList.set(0,bufEquiv[ic],img);
            bFirstEq=false;
        } else {
            eqList.append(bufEquiv[ic],img);
        }
      } 
      else {
        s=bufEquiv[ic];
        i=s.indexOf(":");
        if (i>0) {
            if (bFirstEq) {
                eqList.set(0,s.substring(0,i-1),img);
                bFirstEq=false;
            }
            else eqList.append(s.substring(0,i-1),img);
            eqList.append(s.substring(i+2,s.length()),null);
        } else  eqList.append(s,img);
      }
    
}
void FlushBufEquiv()
{
    int ic;
    
    for (ic=0; ic<bufEquivCount; ic++) {
         if (bufEquiv[ic].indexOf(key)==0) {
             FlushBufEquiv1(ic);
         }
    }
    for (ic=0; ic<bufEquivCount; ic++) {
         if (bufEquiv[ic].indexOf(key)!=0) {
             FlushBufEquiv1(ic);
         }
    }
}        

 public void stop()  {
        synchronized(semaphore) {
            next_state=STATE_STOP;
            semaphore.notify();
        }
  }

public void run() {

   synchronized(semaphore) {
     if (state==STATE_INIT) state=STATE_WAIT;
   }
   while (state != STATE_STOP) {
    try {
        synchronized(semaphore) {
            if (state!=next_state) state=next_state;
        }
        if (state==STATE_FIRST_PREVIEW) {
            FirstPreview();
            synchronized(semaphore) {
               if ((next_state!=STATE_FIRST_EQ) && (next_state!=STATE_NEXT_EQ)) next_state=STATE_NEXT_PREVIEW;
            }
        }
        else if (state==STATE_NEXT_PREVIEW) {
            NextPreview();
            if (pcounter>=par.iPreviewMax) {
                DisplayPreview();
                synchronized(semaphore) {
                    if ( (next_state!=STATE_FIRST_EQ) && (next_state!=STATE_NEXT_EQ) &&
                        (state==STATE_NEXT_PREVIEW) ) {
                       next_state=STATE_WAIT;
                    }
                }
            }
        } 
        else if (state==STATE_FIRST_EQ) {
            bufEquivCount=0;
            FirstEquiv();
            ecounter=0;
            synchronized(semaphore) {
                  next_state=STATE_NEXT_EQ;
           }
        }
        else if (state==STATE_NEXT_EQ) {
            NextEquiv();
            ecounter++;
            if (ecounter>par.iEquivMax) {
                if (bFirstEq) eqList.set(0,par.sNOT_FOUND,null);
                if (buffered) FlushBufEquiv();
                synchronized(semaphore) {
                    if ((state==STATE_NEXT_EQ) && (next_state==STATE_NEXT_EQ)) next_state=STATE_WAIT;
                }
            }
        } 
        else if (state==STATE_WAIT){
           synchronized(semaphore) {
              semaphore.wait();
           }
        } else {
           Thread t = Thread.currentThread();
           t.sleep( 50 );
        }
    }
     catch (InterruptedException e) {
           synchronized(semaphore) {
             state=STATE_STOP;
           }
     }
   }
 }
  
}


public class background  {

    static int iGET_LIST = 1;
    static int iGET_PRON = 2;
    static int iPL_EN = 0;
    static int iEN_PL = 1;
    
    public int iDirection = iPL_EN;
    
    warp dict;
    params par;
    str ustr;
    InternetConnection web;
    threadDict thDict;

    public int iRetCode = 255; /* 255 = wait; -1 = failure; 0 = OK; 1 = panding */
    
    public background(params apar, str astr) {
        web=null;
        ustr=astr;
        par=apar;
        dict = new warp();
        dict.OpenDictionaries();
        
        thDict = new threadDict(dict,par); 
        new Thread(thDict).start();
    }
    

//#if TESTING=="1"
//#     void testing(List list, Image img){
//#         String key = ustr.convProgrammersKbd("a");
//#         thDict.StartEquiv(false,key,list,img);
//#     }
//#     
//#endif
    
  public void stop() {
        thDict.stop();
        Thread t = Thread.currentThread();
        try {
           t.sleep( 500 );
        }
         catch( InterruptedException e ){
        }
    }

    public void FindDicts(Callback callback){
        dict.FindDicts(callback);
    }
   
    void search(boolean onlyExamples, String key, List list, Image img){
        thDict.StartEquiv(onlyExamples,key,list,img);
    }
           
    void SearchPreview(String key,  StringItem[] list){
        
        thDict.StartPreview(key,list);
    }
            
   
    void WebSearch(String sKey, Receiver receiver) {
        if (web==null) {
            web = new InternetConnection(par.sURL, receiver);
        }
        if (par.dictDirection==0) {
            web.Search("num=20&dict=1&form=tw2&dir=pe&key="+sKey);
        } else {
            web.Search("num=20&dict=1&form=tw2&dir=ep&key="+sKey);
        }
       
/*
        iRetCode=1;
        sKey = ustr.convProgrammersKbd(sKey);
        new com.InternetConnection(par.sPE_URL + ustr.convURLcode(sKey), this, iGET_LIST);
 */
    }
    
    void webgetPronunciation(String sPhrase) {
/*        
        iRetCode=1;
        new com.InternetConnection(par.sSAY_URL+ustr.convURLcode(sPhrase), this, iGET_PRON);
*/
    }




}
